﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.Speech.Recognition;
using Microsoft.Speech.Synthesis;
using System.IO;
using System.Globalization;
using System.Threading;
using Microsoft.DirectX.DirectInput;
using System.Xml;

namespace VIPALABVoiceApp
{
    public partial class Form1 : Form
    {
        LocalizationServiceForm lsf = new LocalizationServiceForm();
        
        SpeechRecognitionEngine speechEngine;// = new SpeechRecognitionEngine();
        SpeechSynthesizer speechVoice = new SpeechSynthesizer();
        Grammar grammar;
        CultureInfo culture;
        
        Device xboxGamePad;

        string fileName = "C:\\vipalab.txt";
        string GPSFilename = "C:\\smart2.txt";
        string configFile = "\\config\\config.ini";

        const int MODE = 0;
        const int DIRECTION = 1;
        const int STEER = 2;
        const int GEAR = 3;
        string[] commands = { "close window",  "reset all", "enable robocab", "disable robocab" };
        string[] driving = { "Go", "Back", "Stop", "Turn Left", "Turn Right", "Center", "gear up", "gear down", "Parking" };
        string[] gps_commands = { "Move Left", "Move Right", "Move Up", "Move Down", "find", "route", "clear map", "zoom in", "zoom out", "robocab", "draw line", "throw pin", "erase all" };
        string[] places = { "coffee", "bar", "airport", "atm", "doctor", "restaurant", "hospital", "subway", "shopping", "police"};
        string[] services = { "GPS", "bluetooth", "phone call" };

        int Rx, Ry;
        int Lx, Ly;
        int d_pad = -1;
        int padReferenceValue = 0;
        int padReferenceSteer = 0;
        
        bool gamepadConnected = false;
        bool GPSenabled = false;
        bool placesEnabled = false;
        public static bool use_gps_sensor = false;
        public static bool voiceEnabled = false;

        cross padCross = new cross(8);
        cross padCross2 = new cross(8);

        int steeringValue = 0, accelerationValue = 0, gearingValue;

        int SCREEN_X = Screen.PrimaryScreen.Bounds.Width;
        int SCREEN_Y = Screen.PrimaryScreen.Bounds.Height;
       
        Rectangle old_flash_rect = new Rectangle();
        Rectangle old_parent_rect = new Rectangle();

        public Form1()
        {

            InitializeComponent();

            Bitmap bmp = new Bitmap(gamepadPictureBox.Width, gamepadPictureBox.Height);
            Graphics g = Graphics.FromImage(bmp);
            g.Clear(Color.White);
            gamepadPictureBox.Image = bmp;
            gamePadpictureBox2.Image = bmp;

            startGamepad();

            LoadGUI();

            timerGamePad.Tick += new EventHandler(timerGamePad_Tick);

            lsf.Width = (int)(SCREEN_X * 0.8f);
            lsf.Height = (int)(SCREEN_Y * 0.8f);
            lsf.DesktopLocation = new Point((int)(SCREEN_X * 0.2f / 4), (int)(SCREEN_Y * 0.2f / 2));
            lsf.onButtonPressed += new formButtonPressed(lsf_onButtonPressed);
            lsf.taskFinished += new taskEnd(lsf_taskFinished);

            KeyPreview = true;
            KeyDown += new KeyEventHandler(Form1_KeyDown);

            CheckForIllegalCrossThreadCalls = false;

            if (radioButton1.Checked)
            {
                //timerGamePad.Stop();
                if (speechEngine != null) speechEngine.RecognizeAsyncStop();
                voiceGroupBox.Enabled = false;
                gamepadGroupBox.Enabled = false;
                //languageGroupBox.Enabled = false;

                if (radioButton1.Checked) gamePadLabel.Text = "System Disabled";

                changeFileValue(MODE, "0");
            }

            timerGamePad.Start();
        }

        void readConfigFile()
        {
            if (File.Exists(Directory.GetCurrentDirectory() + configFile))
            {
                use_gps_sensor = Convert.ToBoolean(File.ReadAllLines(Directory.GetCurrentDirectory() + configFile)[0].Split('=')[1]);
            }
        }

        void lsf_taskFinished()
        {
            placesEnabled = false;
        }

        void lsf_onButtonPressed(string buttonName)
        {
            switch (buttonName)
            {
                case "findBtn":
                    placesEnabled = true;
                    break;
            }
        }

        void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Control && e.KeyCode == Keys.F12)
            {
                setFullScreen(false);
            }
        }

        void LoadGUI()
        {
            userGUIFlash.Movie = Directory.GetCurrentDirectory() + "\\assets\\swf\\robocab_demointerface.swf";
            userGUIFlash.FSCommand += new AxShockwaveFlashObjects._IShockwaveFlashEvents_FSCommandEventHandler(userGUIFlash_FSCommand);
        }

        void userGUIFlash_FSCommand(object sender, AxShockwaveFlashObjects._IShockwaveFlashEvents_FSCommandEvent e)
        {
            switch (e.command)
            {
                case "Tweened":
                    checkForTween(e.args);
                    break;

                case "back_btn":
                    if (lsf.Visible)
                        lsf.Hide();
                    break;
            }
            
            //MessageBox.Show(e.command.ToString());
        }

        #region GAMEPAD CODE
        void startGamepad()
        {
            try
            {
                DeviceList gameControllerList = Manager.GetDevices(DeviceClass.GameControl, EnumDevicesFlags.AttachedOnly);
                if (gameControllerList.Count > 0)
                {
                    // Move to the first device
                    gameControllerList.MoveNext();
                    DeviceInstance deviceInstance = (DeviceInstance)gameControllerList.Current;

                    // create a device from this controller.
                    xboxGamePad = new Device(deviceInstance.InstanceGuid);
                    xboxGamePad.SetCooperativeLevel(this, CooperativeLevelFlags.Background | CooperativeLevelFlags.NonExclusive);
                    xboxGamePad.SetDataFormat(DeviceDataFormat.Joystick);
                    xboxGamePad.Acquire();
                    JoystickState js = xboxGamePad.CurrentJoystickState;
                    gamepadConnected = true;
                }
                else
                {
                    MessageBox.Show("No gamepad connected to this computer");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            } 
        }

        void timerGamePad_Tick(object sender, EventArgs e)
        {
            ReadGPSSensor();

            if (xboxGamePad == null)
                return;

            try
            {
                xboxGamePad.Poll();
            }
            catch
            {
                gamepadConnected = false;
                MessageBox.Show("No gamepad connected or connection lost!");
                return;
            }
            if (xboxGamePad.CurrentJoystickState.GetButtons()[6] >= 128)
                manageOrder("reset all");

            if (!gamepadRadioButton.Checked)
                return;
            //Buttons: 0 = A, 1 = B, 2 = X, 3 = Y, 4 = LB, 5 = RB, 6 = Back, 7 = Start
            gamePadLabel.Text = "";

            if (xboxGamePad.CurrentJoystickState.GetButtons()[0] >= 128)
                manageOrder("gear down");
            if (xboxGamePad.CurrentJoystickState.GetButtons()[3] >= 128)
                manageOrder("gear up");
            if (xboxGamePad.CurrentJoystickState.GetButtons()[1] >= 128)
                manageOrder("Parking");

            //0 = UP, 4500 = UPR, 9000 = RIGHT, 135000 = DOR, 180000 = DO, 225000= DOL, 270000 = LEFT, 315000 = UPL
            d_pad = xboxGamePad.CurrentJoystickState.GetPointOfView()[0];

            //TODO: Check for another driver X360WC for vibration and other features or build own wrapper using XInput.
            //xboxGamePad.SendForceFeedbackCommand(ForceFeedbackCommand.SetActuatorsOn);

            int middlePoint = (int)((float)65535 / 2);

            //Minimum percentage from the center of the stick to begin getting orders
            int percentage = (int)(middlePoint * 0.1f);
            
            //Number of accelerations and steerings in charge of dividing the value
            int validValue = (int)((middlePoint - percentage) / 4.0f);

            //Z < 32000 LT Z > 32000 RT
            gamePadLabel.Text = "Gamepad Mode";
            Rx = xboxGamePad.CurrentJoystickState.Rx;
            Ry = xboxGamePad.CurrentJoystickState.Ry;
            Lx = xboxGamePad.CurrentJoystickState.X;
            Ly = xboxGamePad.CurrentJoystickState.Y;
            
            gamepadPictureBox.Invalidate();
            gamePadpictureBox2.Invalidate();

            //ACCELELERATION
            if (Ly < middlePoint - percentage)
            {
                if (Ly < padReferenceValue - validValue)
                {
                    padReferenceValue -= validValue;
                    manageOrder("gear up");
                    manageOrder("Go");
                }
                else if(Ly > padReferenceValue)
                {
                    padReferenceValue += validValue;
                    manageOrder("Back");
                }
            }
            else if (Ly > middlePoint + validValue)
            {
                if (Ly > padReferenceValue + validValue)
                {
                    padReferenceValue += validValue;
                    manageOrder("gear down");
                    manageOrder("Go");
                }
                else if (Ly < padReferenceValue)
                {
                    padReferenceValue -= validValue;
                    manageOrder("Back");
                }
            }
            else
            {
                padReferenceValue = middlePoint - percentage;
                manageOrder("Parking");
                manageOrder("Stop");
            }

            //STEERING
            if (Rx < middlePoint - percentage)
            {
                if (padReferenceSteer > middlePoint - percentage)
                    padReferenceSteer = middlePoint - percentage;

                if (Rx < padReferenceSteer - validValue)
                {
                    padReferenceSteer -= validValue;
                    manageOrder("Turn Left");
                }
                else if (Rx > padReferenceSteer)
                {
                    padReferenceSteer += validValue;
                    manageOrder("Turn Right");
                }
            }
            else if (Rx > middlePoint + percentage)
            {
                if (padReferenceSteer < middlePoint + percentage)
                    padReferenceSteer = middlePoint + percentage;

                if (Rx > padReferenceSteer + validValue)
                {
                    padReferenceSteer += validValue;
                    manageOrder("Turn Right");
                }
                else if (Rx < padReferenceSteer)
                {
                    padReferenceSteer -= validValue;
                    manageOrder("Turn Left");
                }
            }
            else
            {
                padReferenceSteer = middlePoint;
                manageOrder("Center");
            }

        }
        #endregion

        private void Form1_Load(object sender, EventArgs e)
        {
            voiceGroupBox.Enabled = false;

            if (!File.Exists(fileName))
            {
                TextWriter tw = new StreamWriter(fileName);
                tw.WriteLine("0");
                //tw.WriteLine(DIRECTION);
                tw.WriteLine("0");
                //tw.WriteLine(STEER);
                tw.WriteLine("0");
                //tw.WriteLine(GEAR);
                tw.WriteLine("0");
                tw.Close();
            }

            ReadOnlyCollection<RecognizerInfo> rinfos = SpeechRecognitionEngine.InstalledRecognizers();

            foreach (RecognizerInfo rinfo in rinfos)
            {
                languageComboBox.Items.Add(rinfo.Description);
            }

            languageComboBox.SelectedIndex = 0;

            //init();
        }

        private void ReadGPSSensor()
        {
            if (File.Exists(GPSFilename) && use_gps_sensor)
            {
                TextReader tr = new StreamReader(GPSFilename);
                string lineRead = tr.ReadLine();
                lsf.currentLocationX = lineRead.Split(' ')[1];
                lsf.currentLocationY = lineRead.Split(' ')[0];
                tr.Close();
            }
        }

        private void init()
        {
            Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
            
            Choices choices = new Choices();
            choices.Add(driving);
            choices.Add(commands);
            choices.Add(places);
            choices.Add(services);
            choices.Add(gps_commands);
            
            //Create a culture for setting the grammar
            GrammarBuilder grBuilder = new GrammarBuilder(choices);
            grBuilder.Culture = culture;                    
            grammar = new Grammar(grBuilder);
            
            //speechEngine.LoadGrammar(new DictationGrammar());
            speechEngine.LoadGrammar(grammar);
            speechEngine.SpeechRecognized += new EventHandler<SpeechRecognizedEventArgs>(speechEngine_SpeechRecognized);
            speechEngine.RecognizeCompleted += new EventHandler<RecognizeCompletedEventArgs>(speechEngine_RecognizeCompleted);
            speechEngine.AudioStateChanged += new EventHandler<AudioStateChangedEventArgs>(speechEngine_AudioStateChanged);
            //speechEngine.SpeechHypothesized += new EventHandler<SpeechHypothesizedEventArgs>(speechEngine_SpeechHypothesized);

           /* ReadOnlyCollection<InstalledVoice> iv = speechVoice.GetInstalledVoices();
            speechVoice.SpeakCompleted += new EventHandler<SpeakCompletedEventArgs>(speechVoice_SpeakCompleted);
            speechVoice.SpeakStarted += new EventHandler<SpeakStartedEventArgs>(speechVoice_SpeakStarted);
            speechVoice.Rate = -3;*/
            //speechVoice.SelectVoice("MSMike");
            //speechVoice.SelectVoiceByHints(VoiceGender.Male);
        }

        void speechEngine_SpeechHypothesized(object sender, SpeechHypothesizedEventArgs e)
        {
            foreach (RecognizedWordUnit word in e.Result.Words)
            {
                if (speechBox.Lines.Length > 13)
                    speechBox.Text = "";

                //if (robocabSpeaking)
                //return;
                if (word.Confidence < 0.70)
                    return;

                var d2 = new Dictionary<string, string>();
                d2.Add(word.Text.ToUpper(), "string");
                InvokeFlashFunction(userGUIFlash, "setIncommingCommand", d2);

                speechBox.Text += e.Result.Text + "\r\n";

                speechBox.Text += word.Text + " - " + word.Pronunciation + " - " + word.Confidence;

                manageOrder(word.Text);
            }
        }

        void speechEngine_AudioStateChanged(object sender, AudioStateChangedEventArgs e)
        {
            var d = new Dictionary<string, string>();
            //d.Add("1", "1");
            
            if (e.AudioState == AudioState.Silence)
            {
                d.Add("0", "number");
            }
            else if (e.AudioState == AudioState.Speech)
            {
                d.Add("1", "number");
            }

            InvokeFlashFunction(userGUIFlash, "highLightVoiceIcon", d);
        }

        void speechVoice_SpeakStarted(object sender, SpeakStartedEventArgs e)
        {
            speechEngine.RecognizeAsyncCancel();
        }

        void speechVoice_SpeakCompleted(object sender, SpeakCompletedEventArgs e)
        {
            try
            {
                speechEngine.RecognizeAsync(RecognizeMode.Multiple);
            }
            catch   {   }
            
        }

        void speechEngine_RecognizeCompleted(object sender, RecognizeCompletedEventArgs e)
        {
            
        }

        void speechEngine_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
        {
            int wordsCant = 0;
            string orderCommand = "";

            foreach (RecognizedPhrase phrase in e.Result.Alternates)
            {
                if (speechBox.Lines.Length > 13)
                    speechBox.Text = "";

                //if (robocabSpeaking)
                    //return;
                if (phrase.Confidence < 0.50)
                    return;

                var d2 = new Dictionary<string, string>();
                d2.Add(phrase.Text.ToUpper(), "string");
                InvokeFlashFunction(userGUIFlash, "setIncommingCommand", d2);

                speechBox.Text += e.Result.Text + "\r\n";

                speechBox.Text += phrase.Text + " - " + phrase.Confidence;
                
                manageOrder(phrase.Text);
            }
        }

        private void manageOrder(string order)
        {
            if (order == "enable robocab")
                voiceEnabled = true;
            if (order == "disable robocab")
                voiceEnabled = false;

            if (!voiceEnabled)
                return;
            
            if (order == "reset all")
            {
                changeFileValue(DIRECTION, "0");
                changeFileValue(STEER, "0");
                changeFileValue(GEAR, "0");
                changeFileValue(MODE, "0");

                steeringValue = 0;
                accelerationValue = 0;
                gearingValue = 0;

                steerText.Text = steeringValue.ToString();
                speedText.Text = accelerationValue.ToString();
                gearText.Text = gearingValue.ToString();

                radioButton1.Checked = true;
            }
            
            if (vehicleDrivingCheck.Checked || gamepadRadioButton.Checked)
            {
                checkForDriving(order);
                return;
            }

            var d = new Dictionary<string, string>();

            switch (order)
            {
                case "GPS":
                    d.Add("gps_srv", "string");
                    userGUIFlash.BringToFront();
                    InvokeFlashFunction(userGUIFlash, "TweenIn", d);
                    break;

                case "phone call":
                    d.Add("phonecall_srv", "string");
                    userGUIFlash.BringToFront();
                    InvokeFlashFunction(userGUIFlash, "TweenIn", d);
                    break;

                default:
                    break;
            }

            if (GPSenabled)
            {
                checkGPSOrder(order);
            }
            if (placesEnabled)
            {
                checkForPlaces(order);
            }
        }

        private void checkForDriving(string command)
        {
            switch (command)
            {
                case "Go":
                    if (accelerationValue < 4)
                        accelerationValue += 1;
                    changeFileValue(DIRECTION, accelerationValue.ToString());
                    break;

                case "Back":
                    if (accelerationValue > 0)
                        accelerationValue -= 1;
                    changeFileValue(DIRECTION, accelerationValue.ToString());
                    break;

                case "Turn Left":
                    if (steeringValue > -4)
                        steeringValue -= 1;
                    changeFileValue(STEER, steeringValue.ToString());
                    break;

                case "Turn Right":
                    if (steeringValue < 4)
                        steeringValue += 1;
                    changeFileValue(STEER, steeringValue.ToString());
                    break;

                case "Stop":
                    accelerationValue = 0;
                    changeFileValue(DIRECTION, "0");
                    //changeFileValue(GEAR, "0");
                    break;

                case "Center":
                    steeringValue = 0;
                    changeFileValue(STEER, "0");
                    break;

                case "gear up":
                    changeFileValue(GEAR, "1");
                    gearingValue = 1;
                    break;

                case "gear down":
                    changeFileValue(GEAR, "-1");
                    gearingValue = -1;
                    break;

                case "Parking":
                    changeFileValue(GEAR, "0");
                    gearingValue = 0;
                    break;
            }

            steerText.Text = steeringValue.ToString();
            speedText.Text = accelerationValue.ToString();
            gearText.Text = gearingValue.ToString();
        }

        private void checkForTween(string service_name)
        {
            switch (service_name)
            {
                case "gps_srv":
                    GPSenabled = true;
                    lsf.Show(this);
                    lsf.BringToFront();
                    break;

                case "phonecall_srv":
                    break;
            }
        }

        private void checkForUntween(string service_name)
        {
            switch (service_name)
            {
                case "gps_srv":
                    lsf.Hide();
                    GPSenabled = false;
                    placesEnabled = false;
                    break;
            }
        }

        private void checkForPlaces(string order)
        {
            if (order == "find")
                return;
            
            if (order.Contains("restaurant"))
                lsf.searchPlaces("food");
            else if (order.Contains("coffee"))
                lsf.searchPlaces("cafe");
            else if (order.Contains("subway"))
                lsf.searchPlaces("subway_station");
            else if (order.Contains("shopping"))
                lsf.searchPlaces("shopping_mall");
            else
                lsf.searchPlaces(order);

            placesEnabled = false;

        }

        private void checkGPSOrder(string order)
        {
            switch (order)
            {
                case "find":
                    placesEnabled = !placesEnabled;
                    lsf.findBtn_Click(null, null);
                    break;

                case "zoom in":
                    lsf.zoomIn();
                    break;

                case "zoom out":
                    lsf.zoomOut();
                    break;

                case "clear map":
                    lsf.clearPlaces();
                    break;

                case "close window":
                    lsf.Hide();
                    InvokeFlashFunction(userGUIFlash, "TweenOut", null);
                    break;

                case "Move Left":
                    lsf.panHorizontal(-500);
                    break;

                case "Move Right":
                    lsf.panHorizontal(500);
                    break;

                case "Move Up":
                    lsf.panVertical(-500);
                    break;

                case "Move Down":
                    lsf.panVertical(500);
                    break;

                case "draw line":
                    lsf.drawlineBtn_Click(null, null);
                    break;

                case "erase all":
                    lsf.button3_Click(null, null);
                    placesEnabled = false;

                    break;

                case "throw pin":
                    lsf.throwpinBtn_Click(null, null);
                    break;

                case "robocab":
                    lsf.centerOnRobocab();
                    break;
            }
        }

        private void changeFileValue(int line, string value)
        {
            string[] lines = File.ReadAllLines(fileName);
            lines[line] = value;
            File.WriteAllLines(fileName, lines);
        }

        private void changeFileValue(string tagItem, string value)
        {
            string[] lines = File.ReadAllLines(fileName);
            
                      
            for(var i = 0; i < lines.Length; ++i)
            {
                if (lines[i] == tagItem)
                {
                    lines[i + 1] = value;
                    i = lines.Length;
                }
            }

            File.WriteAllLines(fileName, lines);
        }

        private void beginRecognitionBtn_Click(object sender, EventArgs e)
        {
            speechEngine.RecognizeAsync(RecognizeMode.Multiple);
            beginRecognitionBtn.Enabled = false;
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (speechEngine != null)
            {
                speechEngine.RecognizeAsyncCancel();
                speechVoice.SpeakAsyncCancelAll();
            }
            changeFileValue(STEER, "0");
            changeFileValue(DIRECTION, "0");
        }

        private void voiceRadioButton_CheckedChanged(object sender, EventArgs e)
        {
            timerGamePad.Stop();
            voiceGroupBox.Enabled = voiceRadioButton.Checked;
            beginRecognitionBtn.Enabled = voiceRadioButton.Checked;
            //languageGroupBox.Enabled = voiceRadioButton.Checked;
            
            if(voiceRadioButton.Checked) gamePadLabel.Text = "Voice Mode";
            changeFileValue(MODE, "1");
        }

        private void gamepadRadioButton_CheckedChanged(object sender, EventArgs e)
        {
            //beginRecognitionBtn.Enabled = true;
            gamepadGroupBox.Enabled = gamepadConnected;
            //timerGamePad.Start();
            if (gamepadRadioButton.Checked && speechEngine != null) speechEngine.RecognizeAsyncStop();
            
            if(gamepadRadioButton.Checked)
                if (!gamepadConnected) 
                    startGamepad();

            if (gamepadRadioButton.Checked) gamePadLabel.Text = "Gamepad Mode";

            changeFileValue(MODE, "1");
        }

        private void radioButton1_CheckedChanged(object sender, EventArgs e)
        {
            if (radioButton1.Checked)
            {
                //timerGamePad.Stop();
                if (speechEngine != null) speechEngine.RecognizeAsyncStop();
                voiceGroupBox.Enabled = false;
                gamepadGroupBox.Enabled = false;
                voiceRadioButton.Enabled = false;

                var d = new Dictionary<string, string>();
                d.Add("0", "number");

                InvokeFlashFunction(userGUIFlash, "highLightVoiceIcon", d);

                changeFileValue(MODE, "0");

                gamePadLabel.Text = "System Disabled";
         
            }
            
        }

        private void languageButton_Click(object sender, EventArgs e)
        {
            ReadOnlyCollection<RecognizerInfo> rinfos = SpeechRecognitionEngine.InstalledRecognizers();

            foreach (RecognizerInfo rinfo in rinfos)
            {
                if (rinfo.Name == languageComboBox.SelectedItem.ToString())
                {
                    try
                    {
                        speechEngine = new SpeechRecognitionEngine(rinfo);
                        speechEngine.SetInputToDefaultAudioDevice();
                        culture = rinfo.Culture;
                        init();
                        voiceRadioButton.Enabled = true;
                    }
                    catch (Exception ex) 
                    {
                        voiceRadioButton.Checked = false;
                        voiceRadioButton.Enabled = false;
                        MessageBox.Show(ex.Message); 
                        return; 
                    }
                    break;
                }
            }
        }

        private void languageComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            voiceRadioButton.Checked = false;
            voiceRadioButton.Enabled = false;

            if (speechEngine != null)
                speechEngine.RecognizeAsyncStop();
        }

        private void gamepadPictureBox_Paint(object sender, PaintEventArgs e)
        {
            int max_value = 65535;

            int valueX = (int)((float)gamepadPictureBox.Width / max_value * Lx);
            int valueY = (int)((float)gamepadPictureBox.Height / max_value * Ly);

            padCross.update(valueX, valueY);

            Graphics g = e.Graphics;

            g.Clear(Color.White);

            g.DrawLine(new Pen(Brushes.Red), new Point(padCross.X, padCross.Y1), new Point(padCross.X, padCross.Y2));
            g.DrawLine(new Pen(Brushes.Red), new Point(padCross.X1, padCross.Y), new Point(padCross.X2, padCross.Y));

        }

        private void gamePadpictureBox2_Paint(object sender, PaintEventArgs e)
        {
            int max_value = 65535;

            int valueX = (int)((float)gamePadpictureBox2.Width / max_value * Rx);
            int valueY = (int)((float)gamePadpictureBox2.Height / max_value * Ry);

            padCross2.update(valueX, valueY);

            Graphics g = e.Graphics;

            g.Clear(Color.White);

            g.DrawLine(new Pen(Brushes.BlueViolet), new Point(padCross2.X, padCross2.Y1), new Point(padCross2.X, padCross2.Y2));
            g.DrawLine(new Pen(Brushes.BlueViolet), new Point(padCross2.X1, padCross2.Y), new Point(padCross2.X2, padCross2.Y));
        }

        private void aboutToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            MessageBox.Show(this, "This software was developed by Omar Contreras\r\nE-mail:radamanthys009@gmail.com", "Who did this?");
        }

        public double ConvertDegreeAngleToDouble(double degrees, double minutes, double seconds)
        {
            return degrees + (minutes / 60) + (seconds / 3600);
        }

        private void mapsBtn_Click(object sender, EventArgs e)
        {
            lsf.ShowDialog(this); 
        }

        public static XmlDocument InvokeFlashFunction(AxShockwaveFlashObjects.AxShockwaveFlash flash_object, string functionName, Dictionary<string, string> arguments)
        {
            XmlDocument xml = new XmlDocument();
            
            string functionCall = "<invoke name=\"" + functionName + "\" returntype=\"xml\">";

            if(arguments == null)
                functionCall += "</invoke>";
            else
            {
                functionCall += "<arguments>";
                foreach (KeyValuePair<string,string> pair in arguments)
                {
                    functionCall += "<" + pair.Value + ">" + pair.Key + "</" + pair.Value + ">";
                }

                functionCall += "</arguments></invoke>";
            }
            try
            {
                xml.LoadXml(flash_object.CallFunction(functionCall));
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }

            return xml;
        }

        private void FullScreenBtn_Click(object sender, EventArgs e)
        {
            setFullScreen(true);
        }

        private void setFullScreen(bool setFS)
        {
            if (setFS)
            {
                
                old_flash_rect.Location = userGUIFlash.Location;
                old_flash_rect.Size = userGUIFlash.Size;
                WindowState = FormWindowState.Maximized;
                FormBorderStyle = FormBorderStyle.None;
                userGUIFlash.Location = new Point(0, 0);
                userGUIFlash.Width = this.Width;
                userGUIFlash.Height = this.Height;
                userGUIFlash.BringToFront();
            }
            else
            {
                userGUIFlash.Location = old_flash_rect.Location;
                userGUIFlash.Size = old_flash_rect.Size;
                WindowState = FormWindowState.Normal;
                FormBorderStyle = FormBorderStyle.Sizable;
                
            }
        }

        
    }
}
